﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;

using TravModelSpace;
using System.Diagnostics;

namespace TravWinControllerSpace
{
    public partial class TravWinController : Form
    {
        //
        ///// address widget
        //

        private void address_KeyPress (object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char) 13)
            {
                Trav.ChangeCurrentDir (Trav.Presenter.AddressText);
                e.Handled = true;
            }
        }

        //
        ///// folders widget
        //

        private void folders_AfterLabelEdit (object sender, NodeLabelEditEventArgs e)
        {
            folders.LabelEdit = false;

            bool error = true;

            if (String.IsNullOrEmpty (e.Node.Text))
            {
                // Create folder
                if (!String.IsNullOrEmpty (e.Label))
                    error = Trav.CreateDirectory (e.Node.FullPath, e.Label);

                if (error)
                    e.Node.Remove ();
            }
            else
            {
                // Rename folder
                e.Node.EndEdit (false);
                if (!String.IsNullOrEmpty (e.Label))
                    error = Trav.RenameDirectory (e.Node.Parent.FullPath, e.Node.Text, e.Label);

                if (error)
                    e.CancelEdit = true;
            }
        }


        private void folders_AfterSelect (object sender, TreeViewEventArgs e)
        {
            Trav.ChangeCurrentDir (folders.SelectedNode.FullPath);
        }


        private void folders_ItemDrag (object sender, ItemDragEventArgs e)
        {
            TreeNode node = (TreeNode) e.Item;

            string[] dragging = new string[] { node.FullPath };
            DataObject j = new DataObject (DataFormats.FileDrop, dragging);

            DoDragDrop (j, DragDropEffects.Move | DragDropEffects.Copy);
        }


        private void folders_DragOver (object sender, DragEventArgs e)
        {
            DragDropEffects afx = e.AllowedEffect;

            // 2 = right, 4 = shift, 8 = control
            if ((e.KeyState & 8) == 8 && (afx & DragDropEffects.Copy) == DragDropEffects.Copy)
            {
                e.Effect = DragDropEffects.Copy;
                return;
            }

            if ((afx & DragDropEffects.Move) == DragDropEffects.Move)
            {
                TreeView targetFolder = (TreeView) sender;
                Point targetPoint = targetFolder.PointToClient (new Point (e.X, e.Y));
                TreeNode targetNode = folders.GetNodeAt (targetPoint);

                // This case only seems to occur when app launched from the debugger.
                if (targetNode == null)
                    return;

                string targetPath = targetNode.FullPath;

                object sourceObjects = e.Data.GetData (DataFormats.FileDrop);
                if (sourceObjects != null)
                {
                    string[] sourceNames = (string[]) sourceObjects;

                    foreach (string sourceName in sourceNames)
                    {
                        if (targetPath.Length >= sourceName.Length)
                            if (targetPath.Substring (0, sourceName.Length) == sourceName)
                            {
                                e.Effect = DragDropEffects.None;
                                return;
                            }
                    }

                    e.Effect = DragDropEffects.Move;
                    return;
                }
            }

            e.Effect = DragDropEffects.None;
        }


        private void folders_DragDrop (object sender, DragEventArgs e)
        {
            TreeView targetFolder = (TreeView) sender;
            Point targetPoint = targetFolder.PointToClient (new Point (e.X, e.Y));
            TreeNode targetNode = folders.GetNodeAt (targetPoint);

            object sourceObjects = e.Data.GetData (DataFormats.FileDrop);
            if (sourceObjects != null)
            {
                string[] sourceNames = (string[]) sourceObjects;

                if (e.Effect == DragDropEffects.Move)
                    Trav.TransferFiles (sourceNames, targetNode.FullPath);
                else if (e.Effect == DragDropEffects.Copy)
                {
                    Trav.CopyFiles (sourceNames, targetNode.FullPath);
                    Debug.WriteLine ("COPY TO FOLDER");
                }
                else
                    Debug.WriteLine ("folders_DragDrop unhandled");
            }
        }

        //
        ///// details widget
        //

        private void details_AfterLabelEdit (object sender, LabelEditEventArgs e)
        {
            if (e.Label != null)
            {
                string oldBaseName = Trav.Detail.Presenter.BaseName (e.Item);
                string pathName = Trav.Detail.Presenter.FullPathName (e.Item);

                bool isError = Trav.RenameFile (pathName, oldBaseName, e.Label);
                if (isError)
                {
                    // Restore pre-edit value.
                    e.CancelEdit = true;
                    details.Items[e.Item].BeginEdit ();
                }
            }
        }


        private void details_ColumnClick (object sender, ColumnClickEventArgs e)
        {
            ListView widget = (ListView) sender;
            sortDetailsColumn (e.Column, (string) widget.Columns[e.Column].Tag);
        }


        private void details_DoubleClick (object sender, EventArgs e)
        {
            Trav.LaunchSelections ();
        }


        private void details_ItemSelectionChanged (object sender, ListViewItemSelectionChangedEventArgs e)
        {
            if (! SupressStatusUpdates)
                Trav.ShowStatus ("");
        }


        private void details_ItemDrag (object sender, ItemDragEventArgs args)
        {
            String[] dragging = new string[Trav.Detail.Presenter.SelectedCount];
            int i = 0;

            foreach (string fullName in Trav.Detail.Presenter.SelectedFullNames)
                dragging[i++] = fullName;

            DataObject dob = new DataObject (DataFormats.FileDrop, dragging);

            var afx = Trav.Detail.IsSubfoldersShown? DragDropEffects.None : DragDropEffects.Move | DragDropEffects.Copy;
            DoDragDrop (dob, afx);
        }


        private void details_DragOver (object sender, DragEventArgs args)
        {
            DragDropEffects x = args.AllowedEffect;

            // 2 = right, 4 = shift, 8 = control
            if ((args.KeyState & 8) == 8 && (args.AllowedEffect & DragDropEffects.Copy) == DragDropEffects.Copy)
                args.Effect = DragDropEffects.Copy;
            else if ((args.AllowedEffect & DragDropEffects.Move) == DragDropEffects.Move)
                args.Effect = DragDropEffects.Move;
            else
                args.Effect = DragDropEffects.None;
        }


        private void details_DragDrop (object sender, DragEventArgs args)
        {
            object sourceObjects = args.Data.GetData (DataFormats.FileDrop);

            if (sourceObjects != null)
            {
                string[] sourceFiles = (string[]) sourceObjects;

                if (args.Effect == DragDropEffects.Copy)
                    Trav.CopyFiles (sourceFiles, Trav.CurrentDir);
                else if (args.Effect == DragDropEffects.Move)
                    Trav.TransferFiles (sourceFiles, Trav.CurrentDir);
                else
                    Debug.WriteLine ("detail_DragDrop unhandled" + args.Effect);
            }
        }

    }
}
